#include "./select_info_display.hpp"
#include "../layer/models.hpp"
#include "../tools/layer_interface.h"
#include "../ui_message/message.h"
#include "./components.hpp"

namespace qbe::select {

void selectInfoDisplay(ecs::Query query, ecs::Bus& bus) {
  auto& cell = query.get_resource<qlib::Cell::s_ptr>();

  auto layer_interface = query.get_resource<tools::LayerInterfaceObjcet>();
  auto get_layer_name = [&layer_interface](uint32_t layer) {
    auto layer_info = layer_interface.getLayerStyleInfoOnNumFunc(layer);
    std::string layer_name = "";
    if (!layer_info.empty())
      layer_name = layer_info[4];
    return layer_name;
  };
  //获取选择对象
  std::vector<entt::entity> select_arr;
  for (auto [e] : cell->reg.view<select::SelectTag>().each()) {
    select_arr.push_back(e);
  }

  if (!select_arr.empty()) {
    if (select_arr.size() == 1) {
      {
        auto _ptr = cell->reg.try_get<qlib::Polygon::s_ptr>(select_arr[0]);
        if (_ptr) {
          auto poly = *_ptr;
          uint32_t layer = poly->layer;
          std::string layer_name = get_layer_name(layer);
          double area = poly->area();
          double perimeter = poly->perimeter();
          int point_num = poly->points.size();
          bus.send<qbe::UiMessage::SelectInfoMessage>(
              qbe::UiMessage::SelectInfoMessage{QString(QObject::tr("Polygon layer(%1) GDS number(%2) Area(%3) Perimeter(%4) Point(%5)"))
                                                    .arg(QString(layer_name.c_str()))
                                                    .arg(layer)
                                                    .arg(QString::number(area, 'f', 3))
                                                    .arg(QString::number(perimeter, 'f', 3))
                                                    .arg(point_num)});
        }
      }

      {
        auto _ptr = cell->reg.try_get<qlib::Rectangle::s_ptr>(select_arr[0]);
        if (_ptr) {
          auto rec = *_ptr;
          uint32_t layer = rec->layer;
          std::string layer_name = get_layer_name(layer);
          double perimeter = rec->perimeter();
          double width = rec->width;
          double height = rec->height;
          double area = rec->area();
          bus.send<qbe::UiMessage::SelectInfoMessage>(
              qbe::UiMessage::SelectInfoMessage{QString(QObject::tr("Rectangle layer(%1) GDS number(%2) Perimeter(%3) Width(%4) Height(%5) Area(%6)"))
                                                    .arg(QString(layer_name.c_str()))
                                                    .arg(layer)
                                                    .arg(QString::number(perimeter, 'f', 3))
                                                    .arg(QString::number(width, 'f', 3))
                                                    .arg(QString::number(height, 'f', 3))
                                                    .arg(QString::number(area, 'f', 3))});
        }
      }

      {
        auto _ptr = cell->reg.try_get<qlib::Ellipse::s_ptr>(select_arr[0]);
        if (_ptr) {
          auto elli = *_ptr;
          uint32_t layer = elli->layer;
          std::string layer_name = get_layer_name(layer);
          double area = elli->area();
          double x_radius = elli->radius.x;
          double y_radius = elli->radius.y;
          bus.send<qbe::UiMessage::SelectInfoMessage>(
              qbe::UiMessage::SelectInfoMessage{QString(QObject::tr("Cricle layer(%1) GDS number(%2) Area(%3) X_Radius(%4) Y_Radius(%5)"))
                                                    .arg(QString(layer_name.c_str()))
                                                    .arg(layer)
                                                    .arg(QString::number(area, 'f', 3))
                                                    .arg(QString::number(x_radius, 'f', 3))
                                                    .arg(QString::number(y_radius, 'f', 3))});
        }
      }
      {
        auto _ptr = cell->reg.try_get<qlib::Label::s_ptr>(select_arr[0]);
        if (_ptr) {
          auto label = *_ptr;
          uint32_t layer = label->layer;
          std::string layer_name = get_layer_name(layer);
          bus.send<qbe::UiMessage::SelectInfoMessage>(
              qbe::UiMessage::SelectInfoMessage{QString(QObject::tr("Label Layer(%1) GDS number(%2) Text(%3)"))
                                                    .arg(QString(layer_name.c_str()))
                                                    .arg(label->layer)
                                                    .arg(QString(label->text.c_str()))});
        }
      }
      {
        auto _ptr = cell->reg.try_get<qlib::Text::s_ptr>(select_arr[0]);
        if (_ptr) {
          auto text = *_ptr;
          uint32_t layer = text->layer;
          std::string layer_name = get_layer_name(layer);
          bus.send<qbe::UiMessage::SelectInfoMessage>(
              qbe::UiMessage::SelectInfoMessage{QString(QObject::tr("Text graphics Layer(%1) GDS number(%2) Text(%3)"))
                                                    .arg(QString(layer_name.c_str()))
                                                    .arg(layer)
                                                    .arg(QString(text->text.c_str()))});
        }
      }
      {
        auto _ptr = cell->reg.try_get<qlib::KeyPoint::s_ptr>(select_arr[0]);
        if (_ptr) {
          auto key_point = *_ptr;
          bus.send<qbe::UiMessage::SelectInfoMessage>(
              qbe::UiMessage::SelectInfoMessage{QString(QObject::tr("KeyPoint Name(%1) GDS number(%2) X:%3 Y:%4"))
                                                    .arg(QString(key_point->text.c_str()))
                                                    .arg(key_point->layer)
                                                    .arg(QString::number(key_point->origin.x, 'f', 3))
                                                    .arg(QString::number(key_point->origin.y, 'f', 3))});
        }
      }
      {
        auto _ptr = cell->reg.try_get<qlib::Pin::s_ptr>(select_arr[0]);
        if (_ptr) {
          auto pin = *_ptr;
          QString str = QString("%1").arg(QString(pin->text.c_str()));
          auto split_strs = str.split(",");
          bus.send<qbe::UiMessage::SelectInfoMessage>(qbe::UiMessage::SelectInfoMessage{
              QString(QObject::tr("Pin identifier(%1) name(%2) type(%3)")).arg(split_strs[0]).arg(split_strs[1]).arg(split_strs[2])});
        }
      }

      {
        auto _ptr = cell->reg.try_get<qlib::Path::s_ptr>(select_arr[0]);
        if (_ptr) {
          auto line = *_ptr;
          uint32_t layer = line->layer;
          std::string layer_name = get_layer_name(layer);
          double width = line->getLineWidth();
          double center_line_width = line->getCenterWidth();
          double radius = line->getLineRadius();
          int point_num = line->spine.points.size();
          double distance = 0;
          for (int i = 0; i < point_num - 1; i++) {
            distance += line->spine.points[i].distance(line->spine.points[i + 1]);
          }
          bus.send<qbe::UiMessage::SelectInfoMessage>(qbe::UiMessage::SelectInfoMessage{
              QString(QObject::tr("Line Layer(%1) GDS number(%2) Width(%3) Center_Width(%4) Turning_Radius(%5) Point(%6) length(%7)"))
                  .arg(QString(layer_name.c_str()))
                  .arg(layer)
                  .arg(QString::number(width, 'f', 3))
                  .arg(QString::number(center_line_width, 'f', 3))
                  .arg(QString::number(radius, 'f', 3))
                  .arg(point_num)
                  .arg(QString::number(distance, 'f', 3))});
        }
      }

      {
        auto _ptr = cell->reg.try_get<qlib::Reference::s_ptr>(select_arr[0]);
        if (_ptr) {
          auto ref = *_ptr;
          QString info;
          if (ref->getInstanceName() == "") {
            info = QString(QObject::tr("Instance Cell_name(%1)")).arg(QString(ref->cell->name.c_str()));
            if (ref->repetition.type != qlib::RepetitionType::None) {
              QString col = QString("%1").arg(ref->repetition.columns);
              QString row = QString("%1").arg(ref->repetition.rows);
              QString array = row + "x" + col + " Array";
              info = QString(QObject::tr("Instance(%1) Cell_name(%2)")).arg(array).arg(QString(ref->cell->name.c_str()));
            }
          } else {
            info =
                QString(QObject::tr("Instance Cell_name(%1) Ins_name(%2)")).arg(QString(ref->cell->name.c_str())).arg(ref->getInstanceName().c_str());
            if (ref->repetition.type != qlib::RepetitionType::None) {
              QString col = QString("%1").arg(ref->repetition.columns);
              QString row = QString("%1").arg(ref->repetition.rows);
              QString array = row + "x" + col + QObject::tr(" Array");
              info = QString(QObject::tr("Instance(%1) Cell_name(%2) Ins_name(%3)"))
                         .arg(array)
                         .arg(QString(ref->cell->name.c_str()))
                         .arg(ref->getInstanceName().c_str());
            }
          }
          bus.send<qbe::UiMessage::SelectInfoMessage>(qbe::UiMessage::SelectInfoMessage{info});
        }
      }
    } else {
      QString info = QString(QObject::tr("Selected number: "));
      unsigned Instance_num = 0;
      unsigned line_num = 0;
      unsigned rectangle_num = 0;
      unsigned circle_num = 0;
      unsigned polygon_num = 0;
      unsigned keyPoint_num = 0;
      unsigned label_num = 0;
      unsigned text_num = 0;
      unsigned pin_num = 0;

      for (auto i : select_arr) {
        {
          auto _ptr = cell->reg.try_get<qlib::Reference::s_ptr>(i);
          if (_ptr) {
            ++Instance_num;
          }
        }

        {
          auto _ptr = cell->reg.try_get<qlib::Polygon::s_ptr>(i);
          if (_ptr) {
            ++polygon_num;
          }
        }

        {
          auto _ptr = cell->reg.try_get<qlib::Rectangle::s_ptr>(i);
          if (_ptr) {
            ++rectangle_num;
          }
        }

        {
          auto _ptr = cell->reg.try_get<qlib::Ellipse::s_ptr>(i);
          if (_ptr) {
            ++circle_num;
          }
        }

        {
          auto _ptr = cell->reg.try_get<qlib::Path::s_ptr>(i);
          if (_ptr) {
            ++line_num;
          }
        }
        {
          auto _ptr = cell->reg.try_get<qlib::Text::s_ptr>(i);
          if (_ptr) {
            ++text_num;
          }
        }
        {
          auto _ptr = cell->reg.try_get<qlib::Label::s_ptr>(i);
          if (_ptr) {
            ++label_num;
          }
        }
        {
          auto _ptr = cell->reg.try_get<qlib::KeyPoint::s_ptr>(i);
          if (_ptr) {
            ++keyPoint_num;
          }
        }
        {
          auto _ptr = cell->reg.try_get<qlib::Pin::s_ptr>(i);
          if (_ptr) {
            ++pin_num;
          }
        }
      }
      if (Instance_num != 0)
        info += QString(QObject::tr("Instance(%1) ")).arg(Instance_num);
      if (line_num != 0)
        info += QString(QObject::tr("Line(%1) ")).arg(line_num);
      if (rectangle_num != 0)
        info += QString(QObject::tr("Rectangle(%1) ")).arg(rectangle_num);
      if (circle_num != 0)
        info += QString(QObject::tr("Circle(%1) ")).arg(circle_num);
      if (polygon_num != 0)
        info += QString(QObject::tr("Polygon(%1) ")).arg(polygon_num);
      if (keyPoint_num != 0)
        info += QString(QObject::tr("Keypoint(%1) ")).arg(keyPoint_num);
      if (label_num != 0)
        info += QString(QObject::tr("Label(%1) ")).arg(label_num);
      if (text_num != 0)
        info += QString(QObject::tr("Text(%1) ")).arg(text_num);
      if (pin_num != 0)
        info += QString(QObject::tr("Pin(%1) ")).arg(pin_num);
      bus.send<qbe::UiMessage::SelectInfoMessage>(qbe::UiMessage::SelectInfoMessage{info});
    }
  } else {
    bus.send<qbe::UiMessage::SelectInfoMessage>(qbe::UiMessage::SelectInfoMessage{QString()});
  }
}
void SelectInfoDisplayPlugin::build(ecs::App& app) {
  app.add_systems<ecs::stage::PostUpdate>(selectInfoDisplay);
}

}  // namespace qbe::select